﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using System.Windows.Controls;
using Microsoft.Kinect;
using System.Windows;
using System.IO;
using Kinect.Toolbox;
using VitrineInterativa;
using Microsoft.Speech.Recognition;
using System.Windows.Threading;
using Microsoft.Speech.AudioFormat;
using System.ComponentModel;

namespace KinectControl
{
    public enum ImageType
    {
        Color,
        Depth,
    }

    public class JointMapping
    {
        /// <summary>
        /// This is the joint we are looking at
        /// </summary>
        public Joint Joint { get; set; }

        /// <summary>
        /// This is the point mapped into the target displays
        /// </summary>
        public Point MappedPoint { get; set; }
    }

    public class KinectController : IDisposable
    {
        #region === Propriedades ===
        //Kinect
        internal KinectSensor runtime;
        byte[] bytePixelData;
        short[] shortPixelData;
        Skeleton[] skeletons;
        private List<Dictionary<JointType, JointMapping>> jointMappings = new List<Dictionary<JointType, JointMapping>>();

        //Audio
        SpeechRecognitionEngine speechRecognizer;
        DispatcherTimer readyTimer;

        //Kinect Toolbox
        private SwipeGestureDetector swipeGestosMaoDireita;
        private SwipeGestureDetector swipeGestosMaoEsquerda;

        //private TemplatedGestureDetector circleGesto;
        //private string circleKBPath = Path.Combine(Environment.CurrentDirectory, @"circleKB.save");//Path.Combine(Environment.CurrentDirectory, @"data\circleKB.save");

        //Tempo Tutorial
        private DateTime timeCallTutorial { get; set; }
        private DateTime timeCaptacao { get; set; }
        private DateTime timeContinuoCaptacao { get; set; }

        //Controles Gestos
        //bool isForwardGestureActive = false;
        //bool isBackGestureActive = false;
        bool isGestoParaInicio = false;
        bool isGestoParaFim = false;
        bool isInteracao10seg = false;
        bool isCaptacao = false;

        bool maoPassouCabeca = false;
        bool maosFrente = false;
        bool direitaMaoFrente = false;
        bool esquerdaMaoFrente = false;
        bool isDuasMaosExtendidas = false;

        //ID do Skeleton
        int firstSkeleton = 0;

        //Gesto Push
        bool isPush = false;

        private const string RecognizerId = "SR_MS_en-US_Kinect_10.0";
        //bool shouldContinue = true;

        #region === Eventos Gestos
        public delegate void PosicoesHandler(object args);
        public event PosicoesHandler posicoesMembros;

        public delegate void VideoFrameHandler(object args);
        public event VideoFrameHandler videoFrameKinect;

        //public delegate void maoDireitaExtendida();
        //public event maoDireitaExtendida ExtendeMaoDireita;

        //public delegate void maoEsquerdaExtendida();
        //public event maoEsquerdaExtendida ExtendeMaoEsquerda;

        public delegate void maoDireitaFrente();
        public event maoDireitaFrente FrenteMaoDireita;

        public delegate void maoEsquerdaFrente();
        //public event maoEsquerdaFrente FrenteMaoEsquerda;

        public delegate void maoDireitaOrelha();
        /// <summary>
        /// Evento para Pausar Apresentação
        /// </summary>
        public event maoDireitaOrelha MaoAcimaCabeca;

        public delegate void callTutorial();
        public event callTutorial ChamaTutorial;

        public event EventHandler SwipeDireita;

        public event EventHandler SwipeEsquerda;

        public event EventHandler AudioNext;
        public event EventHandler AudioBack;
        public event EventHandler AudioEnter;
        public event EventHandler AudioReturn;
        public event EventHandler AudioPause;
        public event EventHandler AudioZoom;

        //public event EventHandler MakeCirculo;

        public event EventHandler MaosFrente;
        public event EventHandler DuasMaosExtendidas;
        public event EventHandler<MyEventArgs> GetCoordenadas;
        private bool isFrenteMaoDireita = false;

        //Eventos para Video FullScreen
        public event EventHandler AtivaVideoFull;
        public event EventHandler DesativaVideoFull;
        bool VideoFullAtivado = false;

        #endregion

        #endregion

        #region Gestos

        public KinectController()
        {
            try
            {
                this.runtime = KinectSensor.KinectSensors[0]; //Runtime.Kinects[0];

                if (this.runtime == null)
                    throw new Exception("Runtime está nulo");

                //Swipe Gestos Framework
                //Mão Direita
                this.swipeGestosMaoDireita = new SwipeGestureDetector(15);
                this.swipeGestosMaoDireita.OnGestureDetected += GestoDectectadoMaoDireita;

                //Mão Esquerda
                this.swipeGestosMaoEsquerda = new SwipeGestureDetector(15);
                this.swipeGestosMaoEsquerda.OnGestureDetected += GestoDectectadoMaoEsquerda;

                //using (Stream recordStream = File.Open(circleKBPath, FileMode.OpenOrCreate))
                //{
                //    this.circleGesto = new TemplatedGestureDetector("Circle", recordStream);
                //    this.circleGesto.TraceTo(new Canvas(), Colors.Red);
                //    this.circleGesto.OnGestureDetected += GestoDectectadoMaoDireita;
                //}

                /*//Itens Kinect 
                //Since only a color video stream is needed, RuntimeOptions.UseColor is used.
                runtime.Initialize(RuntimeOptions.UseColor | RuntimeOptions.UseSkeletalTracking);
                runtime.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(runtime_SkeletonFrameReady);
                runtime.VideoFrameReady += new EventHandler<ImageFrameReadyEventArgs>(runtime_VideoFrameReady);
                
                //You can adjust the resolution here.
                runtime.VideoStream.Open(ImageStreamType.Video, 2, ImageResolution.Resolution640x480, ImageType.Color);
                //runtime.NuiCamera.ElevationAngle = -27;
                runtime.NuiCamera.ElevationAngle = 0;*/

                /*New SDK*/
                this.runtime.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
                this.runtime.DepthStream.Enable(DepthImageFormat.Resolution320x240Fps30);
                this.runtime.SkeletonStream.Enable();

                this.runtime.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(runtime_ColorFrameReady);
                this.runtime.DepthFrameReady += new EventHandler<DepthImageFrameReadyEventArgs>(runtime_DepthFrameReady);
                this.runtime.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(runtime_SkeletonFrameReady);

                //Seta Near Mode
                if(Config.AtivarNearMode.ToUpper().Equals("S"))
                    this.runtime.DepthStream.Range = DepthRange.Near;

                runtime.Start();

                this.timeCallTutorial = DateTime.Now;
                this.timeCaptacao = DateTime.Now;
                this.timeContinuoCaptacao = DateTime.Now;

            }
            catch (ArgumentOutOfRangeException)
            {
                //throw new Exception("Sensor de movimento não encontrado.");
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

        }

        void runtime_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            //Contador skeletons
            long skeletonsCount = 0;
            
            bool receivedData = false;

            using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
            {
                if (skeletonFrame != null)
                {

                    if (skeletons == null) //allocate the first time
                    {

                        skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
                    }

                    //Popula variavel skeletons com os pontos mapeados
                    skeletonFrame.CopySkeletonDataTo(skeletons);

                    if (skeletons != null)
                        skeletonsCount = skeletons.Where(s => s.TrackingState == SkeletonTrackingState.Tracked).Count();
                    if (skeletonsCount > 0)
                    {
                        receivedData = true;
                    }
                }

            }

            if (receivedData)
            {
                DateTime dtAgora = DateTime.Now;
                double segDiffCaptacao = (dtAgora - this.timeContinuoCaptacao).TotalSeconds;

                //Verifica o tempo continuo de interação
                if (segDiffCaptacao > 9 && !this.isInteracao10seg)
                {
                    //Aumenta o contador caso haja 10 seg de interação
                    Config.NumInteracao += 1;
                    this.isInteracao10seg = true;
                }

                //Verifica qtd de captação
                if (!this.isCaptacao)
                {
                    Config.NumCaptacao += skeletonsCount;
                    this.isCaptacao = true;

                    //Captou.. desativa video full
                    if (Config.AtivarVideoFullScreen.ToUpper().Equals("S")) //Parametrização
                    {
                        if (this.DesativaVideoFull != null)
                            this.DesativaVideoFull(null, null);

                        this.VideoFullAtivado = false;
                    }
                }

                //Está captando.. reseta tempo
                this.timeCaptacao = DateTime.Now;

                //DateTime agora = DateTime.Now;

                //double segDiff = (agora - this.timeCallTutorial).TotalSeconds;

                //Chama tutorial se ficar 60 seg sem captar ninguém
                //if (segDiff > Config.IntervaloTutorial)
                //{
                //    if (this.ChamaTutorial != null)
                //        this.ChamaTutorial();

                //    //Resta tempo
                //    this.timeCallTutorial = DateTime.Now;
                //}
                //else
                //    this.timeCallTutorial = DateTime.Now;

                // DISPLAY OR PROCESS IMAGE DATA IN skeletons HERE
                Joint Head = new Joint();
                Joint HandLeft = new Joint();
                Joint HandRight = new Joint();

                //Busca o primeiro skeleton tracked no array
                //Skeleton skeletonTracked = null;
                //skeletonTracked = (from s in skeletons
                //                   where s.TrackingState == SkeletonTrackingState.Tracked && s.TrackingId == this.firstSkeleton
                //                   select s).FirstOrDefault();

                ////Se nada foi captado pela outra pessoa
                //if (skeletonTracked == null)
                //{
                //    this.firstSkeleton = (from s in skeletons
                //                          where s.TrackingState == SkeletonTrackingState.Tracked
                //                          select s).FirstOrDefault().TrackingId;

                //    //skeletonTracked = (from s in skeletons
                //    //                   where s.TrackingState == SkeletonTrackingState.Tracked
                //    //                   select s).FirstOrDefault();
                //}

                Skeleton skeletonTracked = null;
                skeletonTracked = (from s in skeletons
                                   where s.TrackingState == SkeletonTrackingState.Tracked
                                   select s).FirstOrDefault();

                //Encontra os pontos especificos
                if (skeletonTracked != null)
                {
                    Head = skeletonTracked.Joints[JointType.Head];
                    HandLeft = skeletonTracked.Joints[JointType.HandLeft];
                    HandRight = skeletonTracked.Joints[JointType.HandRight];
                }

                //Adiciona ao objecto Swipe para Mão Direita
                this.swipeGestosMaoDireita.Add(HandRight.Position, this.runtime);

                //Adicionar ao objeto Swipe para Mão Esquerda
                this.swipeGestosMaoEsquerda.Add(HandLeft.Position, this.runtime);

                //Adiciona coordenadas para analise de Circle
                //this.circleGesto.Add(HandLeft.Position, this.runtime);

                //Lista de coordenadas dos gestos
                List<CoordenadasModel> ListaMembros = new List<CoordenadasModel>();
                ListaMembros.Add(new CoordenadasModel() { Membro = "Head", Joint = Head });
                ListaMembros.Add(new CoordenadasModel() { Membro = "HandRight", Joint = HandRight });
                ListaMembros.Add(new CoordenadasModel() { Membro = "HandLeft", Joint = HandLeft });

                //Envia Coordenadas
                if (this.GetCoordenadas != null)
                    this.GetCoordenadas(null, new MyEventArgs() { message = "Membros Mapeados", parameter = ListaMembros });

                //Processa Gestos para dispardo dos eventos - Postures
                this.ProcessaGestos(Head, HandRight, HandLeft);
            }
            else //Não detectou ngm
            {
                //10 segundos sem captção.. então reseta td
                DateTime dtAgora = DateTime.Now;
                double segDiffCaptacao = (dtAgora - this.timeCaptacao).TotalSeconds;

                if (segDiffCaptacao > Config.TempoSemCaptacao)
                {
                    this.timeCaptacao = DateTime.Now;
                    this.timeContinuoCaptacao = DateTime.Now;
                    this.isCaptacao = false;
                    this.isInteracao10seg = false;

                    //Sem ngm captado..Ativa o video na tela toda
                    if (Config.AtivarVideoFullScreen.ToUpper().Equals("S")) //Parametrização
                        if (!VideoFullAtivado)
                        {
                            if (this.AtivaVideoFull != null)
                                this.AtivaVideoFull(null, null);

                            this.VideoFullAtivado = true;
                        }
                }

            }

        }

        void runtime_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
        {
            bool receivedData = false;

            using (DepthImageFrame depthImageFrame = e.OpenDepthImageFrame())
            {

                if (depthImageFrame != null)
                {

                    if (shortPixelData == null) //allocate the first time
                    {

                        shortPixelData = new short[depthImageFrame.PixelDataLength];

                    }

                    //depthImageFrame.CopyPixelDataTo(shortPixelData);

                    receivedData = true;
                }

            }

            if (receivedData)
            {
                
                // DISPLAY OR PROCESS IMAGE DATA IN pixelData HERE

                //TODO: Mesma logica do ColorFrameReady cria imagem Espectro

            }


        }

        void runtime_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
        {
            bool receivedData = false;

            int width = 0;
            int height = 0;

            //Informações captadas em video
            using (ColorImageFrame colorImageFrame = e.OpenColorImageFrame())
            {

                if (colorImageFrame != null)
                {

                    if (bytePixelData == null)
                    //allocate the first time
                    {
                        //Bytes da Imagem
                        bytePixelData = new byte[colorImageFrame.PixelDataLength];

                    }

                    colorImageFrame.CopyPixelDataTo(bytePixelData);

                    width = colorImageFrame.Width;
                    height = colorImageFrame.Height;

                    receivedData = true;
                }


            }

            if (receivedData)
            {
                // DISPLAY
                //OR PROCESS IMAGE DATA IN pixelData HERE

                //bytePixelData

                //Cria o Source da Imagem
                BitmapSource bitMap = BitmapSource.Create(width, height, 96, 96, PixelFormats.Bgr32, null, bytePixelData, width * PixelFormats.Bgr32.BitsPerPixel / 8);

                //Envia o Source para o componente Image.Source
                if (videoFrameKinect != null)
                    videoFrameKinect(bitMap);
            }


        }

        /// <summary>
        /// Método que processa os gestos
        /// </summary>
        /// <param name="head">Posição da cabeça</param>
        /// <param name="rightHand">Posição mão direita</param>
        /// <param name="leftHand">Posição mão esquerda</param>
        private void ProcessaGestos(Joint head, Joint rightHand, Joint leftHand)
        {
            ////Mão direita extendida
            //if (rightHand.Position.X > head.Position.X + 0.50)
            //{
            //    if (!isBackGestureActive && !isForwardGestureActive)
            //    {
            //        isForwardGestureActive = true;

            //        //Move coverflow para direita
            //        if (ExtendeMaoDireita != null)
            //            ExtendeMaoDireita();
            //    }
            //}
            //else
            //{
            //    isForwardGestureActive = false;
            //}

            ////Mão esquerda extendida
            //if (leftHand.Position.X < head.Position.X - 0.50)
            //{
            //    if (!isBackGestureActive && !isForwardGestureActive)
            //    {
            //        isBackGestureActive = true;
            //        //Move coverflow para esquerda
            //        if (ExtendeMaoEsquerda != null)
            //            ExtendeMaoEsquerda();
            //    }
            //}
            //else
            //{
            //    isBackGestureActive = false;
            //}

            //Duas Mãos extendidas
            if ((rightHand.Position.X > head.Position.X + 0.50) && (leftHand.Position.X < head.Position.X - 0.50))
            {
                if (!isDuasMaosExtendidas)
                {
                    isDuasMaosExtendidas = true;

                    if (DuasMaosExtendidas != null)
                        DuasMaosExtendidas(null, null);
                }
            }
            else if ((rightHand.Position.X < head.Position.X + 0.50) && (leftHand.Position.X > head.Position.X - 0.50))
                isDuasMaosExtendidas = false;

            if (Config.UsarUmaMaoEntrar.Equals("S"))
            {
                //Uma mão para frente - Direitta
                if (rightHand.Position.Z < head.Position.Z - 0.60)
                {
                    if (MaosFrente != null && !this.direitaMaoFrente)
                    {
                        MaosFrente(null, null);
                        this.direitaMaoFrente = true;
                    }
                }
                else if (rightHand.Position.Z > head.Position.Z - 0.60)
                    this.direitaMaoFrente = false;

                //Uma mão para frente - Direitta
                if (leftHand.Position.Z < head.Position.Z - 0.60)
                {
                    if (MaosFrente != null && !this.esquerdaMaoFrente)
                    {
                        MaosFrente(null, null);
                        this.esquerdaMaoFrente = true;
                    }
                }
                else if (leftHand.Position.Z > head.Position.Z - 0.60)
                    this.esquerdaMaoFrente = false;
            }
            else
            {
                //Duas Mãos para frente            
                if (rightHand.Position.Z < head.Position.Z - 0.50 && leftHand.Position.Z < head.Position.Z - 0.50)
                {
                    if (MaosFrente != null && !this.maosFrente)
                    {
                        MaosFrente(null, null);
                        this.maosFrente = true;
                    }
                }
                else if (rightHand.Position.Z > head.Position.Z - 0.50 && leftHand.Position.Z > head.Position.Z - 0.50)
                    this.maosFrente = false;
            }



            //Gesto Push                        
            //Mão direita para frente
            if ((rightHand.Position.Z < head.Position.Z - 0.60) && (leftHand.Position.X > head.Position.X - 0.20))
            {
                if (FrenteMaoDireita != null && !this.isFrenteMaoDireita)
                {
                    this.FrenteMaoDireita();
                    this.isFrenteMaoDireita = true;
                }
            }
            else if (rightHand.Position.Z > head.Position.Z - 0.60)
                this.isFrenteMaoDireita = false;

            ////Mão esquerda para frente
            //if ((leftHand.Position.Z < head.Position.Z - 0.50) && ((leftHand.Position.X > head.Position.X - 0.20)))
            //{
            //    if (!isGestoParaInicio && !isGestoParaFim)
            //    {
            //        isGestoParaFim = true;

            //        //Move coverflow para inicio
            //        if (FrenteMaoEsquerda != null)
            //            FrenteMaoEsquerda();
            //    }
            //}
            //else
            //{
            //    isGestoParaFim = false;
            //}


            //Mão acima da cabeça
            if (rightHand.Position.Y > head.Position.Y && !maoPassouCabeca)
            {
                //Pausa apresentação
                if (MaoAcimaCabeca != null)
                {
                    MaoAcimaCabeca();
                    maoPassouCabeca = true;
                }
            }
            else if (rightHand.Position.Y < head.Position.Y)
                maoPassouCabeca = false;
        }

        /// <summary>
        /// Evento de detecção de Gesto Swipe Mão Direita
        /// =====================
        /// Gestos Disponiveis
        /// =====================
        /// SwipeToLeft
        /// SwipeToRight
        /// Circle
        /// </summary>
        /// <param name="obj">Gesto realizado</param>
        void GestoDectectadoMaoDireita(string obj)
        {
            if (!string.IsNullOrEmpty(obj))
            {
                if (obj.Equals("SwipeToLeft"))
                {
                    this.SwipeEsquerda(this, new MyEventArgs() { message = obj });
                }
                else if (obj.Equals("SwipeToRight"))
                {
                    this.SwipeDireita(this, new MyEventArgs() { message = obj });
                }
                //else if (obj.Equals("Circle"))
                //{
                //    this.MakeCirculo(this, new MyEventArgs() { message = obj });
                //}
            }
        }

        /// <summary>
        /// Evento de detecção de Gesto Swipe Mão Esquerda
        /// =====================
        /// Gestos Disponiveis
        /// =====================
        /// SwipeToLeft
        /// SwipeToRight
        /// Circle
        /// </summary>
        /// <param name="obj">Gesto realizado</param>
        void GestoDectectadoMaoEsquerda(string obj)
        {
            if (!string.IsNullOrEmpty(obj))
            {
                if (obj.Equals("SwipeToLeft"))
                {
                    this.SwipeEsquerda(this, new MyEventArgs() { message = obj });
                }
                else if (obj.Equals("SwipeToRight"))
                {
                    this.SwipeDireita(this, new MyEventArgs() { message = obj });
                }
                //else if (obj.Equals("Circle"))
                //{
                //    this.MakeCirculo(this, new MyEventArgs() { message = obj });
                //}
            }
        }

        /// <summary>
        /// Método para fechar as conexões com Kinect
        /// </summary>
        public void Dispose()
        {
            if(this.swipeGestosMaoDireita != null)
                this.swipeGestosMaoDireita.OnGestureDetected -= GestoDectectadoMaoDireita;
            if (this.swipeGestosMaoEsquerda != null)
                this.swipeGestosMaoEsquerda.OnGestureDetected -= GestoDectectadoMaoEsquerda;

            //this.AtivaVideoFull -= this.AtivaVideoFull;
            //this.DesativaVideoFull -= this.DesativaVideoFull;

            //this.circleGesto.OnGestureDetected -= GestoDectectadoMaoDireita;
            if (runtime != null)
            {
                runtime.Stop();
            }
            //shouldContinue = false;
        }

        #endregion

        #region Speech Recognition Methods
        private static RecognizerInfo GetKinectRecognizer()
        {
            Func<RecognizerInfo, bool> matchingFunc = r =>
            {
                string value;
                r.AdditionalInfo.TryGetValue("Kinect", out value);
                return "True".Equals(value, StringComparison.InvariantCultureIgnoreCase) && "en-US".Equals(r.Culture.Name, StringComparison.InvariantCultureIgnoreCase);
            };
            return SpeechRecognitionEngine.InstalledRecognizers().Where(matchingFunc).FirstOrDefault();
        }

        public void InitializeSpeechRecognition()
        {
            RecognizerInfo ri = GetKinectRecognizer();

            if (ri == null)
            {
                //                    @"There was a problem initializing Speech Recognition.
                //Ensure you have the Microsoft Speech SDK installed.",
                return;
            }

            try
            {
                speechRecognizer = new SpeechRecognitionEngine(ri.Id);
            }
            catch
            {
                //                    @"There was a problem initializing Speech Recognition.
                //Ensure you have the Microsoft Speech SDK installed and configured.",
            }

            var phrases = new Choices();
            phrases.Add("next");
            phrases.Add("back");
            phrases.Add("return");
            phrases.Add("enter");
            phrases.Add("pause");
            phrases.Add("play");
            phrases.Add("small");
            phrases.Add("big");

            var gb = new GrammarBuilder();
            //Specify the culture to match the recognizer in case we are running in a different culture.                                 
            gb.Culture = ri.Culture;
            gb.Append(phrases);

            // Create the actual Grammar instance, and then load it into the speech recognizer.
            var g = new Grammar(gb);

            speechRecognizer.LoadGrammar(g);
            speechRecognizer.SpeechRecognized += SreSpeechRecognized;
            speechRecognizer.SpeechHypothesized += SreSpeechHypothesized;
            speechRecognizer.SpeechRecognitionRejected += SreSpeechRecognitionRejected;

            this.readyTimer = new DispatcherTimer();
            this.readyTimer.Tick += this.ReadyTimerTick;
            this.readyTimer.Interval = new TimeSpan(0, 0, 4);
            this.readyTimer.Start();

        }

        private void ReadyTimerTick(object sender, EventArgs e)
        {
            this.StartSpeechRecognition();
            this.readyTimer.Stop();
            this.readyTimer = null;
        }

        private void StartSpeechRecognition()
        {
            if (runtime == null || speechRecognizer == null)
                return;

            var audioSource = this.runtime.AudioSource;
            audioSource.BeamAngleMode = BeamAngleMode.Adaptive;

            var kinectStream = audioSource.Start();

            speechRecognizer.SetInputToAudioStream(
                    kinectStream, new SpeechAudioFormatInfo(EncodingFormat.Pcm, 16000, 16, 1, 32000, 2, null));
            speechRecognizer.RecognizeAsync(RecognizeMode.Multiple);

        }

        void SreSpeechRecognitionRejected(object sender, SpeechRecognitionRejectedEventArgs e)
        {
            //Trace.WriteLine("\nSpeech Rejected, confidence: " + e.Result.Confidence);
        }

        void SreSpeechHypothesized(object sender, SpeechHypothesizedEventArgs e)
        {
            //Trace.Write("\rSpeech Hypothesized: \t{0}", e.Result.Text);
        }

        void SreSpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            //This first release of the Kinect language pack doesn't have a reliable confidence model, so 
            //we don't use e.Result.Confidence here.
            if (e.Result.Confidence < 0.70)
            {
                //Trace.WriteLine("\nSpeech Rejected filtered, confidence: " + e.Result.Confidence);
                return;
            }

            //Trace.WriteLine("\nSpeech Recognized, confidence: " + e.Result.Confidence + ": \t{0}", e.Result.Text);

            if (e.Result.Text == "next")
            {
                this.AudioNext(this, e);
            }
            else if (e.Result.Text == "back")
            {
                this.AudioBack(this, e);
            }
            else if (e.Result.Text == "return")
            {
                this.AudioReturn(this, e);
            }
            else if (e.Result.Text == "enter")
            {
                this.AudioEnter(this, e);
            }
            else if (e.Result.Text == "pause" || e.Result.Text == "play")
            {
                this.AudioPause(this, e);
            }
            else if (e.Result.Text == "small" || e.Result.Text == "big")
            {
                this.AudioZoom(this, e);
            }
        }

        #endregion                
    }
}
